﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Text;
using Hutech.Authentication.Library.Data;
using System.Collections;
using log4net;

namespace Hutech.Authentication.Library.Business
{
    public class SiteUser
    {
        /// <summary>
        /// Lop mo ta cau truc va cac xu ly cua doi tuong SiteUser.
        /// Author:         tsandtm
        /// Created Date:   08/3/2010
        /// </summary>
        #region Contructors
        public SiteUser()
        {
        }

        public SiteUser(Guid userId)
        {
            _GetUser(userId);
        }

        public SiteUser(string userLoginName)
        {
            _GetUser(userLoginName);
        }

        #endregion

        #region Private Properties

        private static readonly ILog log = LogManager.GetLogger(typeof(SiteUser));

        private Guid _UserId = Guid.Empty;
        private Guid _SiteId = Guid.Empty;
        private string _LoginName = string.Empty;
        private string _Email = string.Empty;
        private string _Name = string.Empty;
        private string _Password = string.Empty;
        private DateTime _DateCreated = DateTime.MinValue;
        private bool _IsDeleted = false;
        private bool _IsLockedOut = false;
        private DateTime _LastActivityDate = DateTime.MinValue;
        private DateTime _LastLoginDate = DateTime.MinValue;
        private DateTime _LastPasswordChangedDate = DateTime.MinValue;
        private DateTime _LastLockoutDate = DateTime.MinValue;
        private int _FailedPwdAttemptCount = -1;
        private DateTime _FailedPwdAttemptWindowStart = DateTime.MinValue;
        private int _FailedPwdAnswerCount = -1;
        private DateTime _FailedPwdAnswerWindowStart = DateTime.MinValue;
        private string _PasswordSalt = string.Empty;
        private string _Comment = string.Empty;
        private bool _IsBuildInUser = false;

        #endregion

        #region Public Properties

        public Guid UserId
        {
            get
            {
                return _UserId;
            }
        }

        public Guid SiteId
        {
            get
            {
                return _SiteId;
            }
            set
            {
                _SiteId = value;
            }
        }
        public string LoginName
        {
            get
            {
                return _LoginName;
            }
            set
            {
                _LoginName = value;
            }
        }
        public string Email
        {
            get
            {
                return _Email;
            }
            set
            {
                _Email = value;
            }
        }
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }

        public string Password
        {
            get
            {
                return _Password;
            }
            set
            {
                _Password = value;
            }
        }

        public DateTime DateCreated
        {
            get
            {
                return _DateCreated;
            }
        }

        public bool IsDeleted
        {
            get
            {
                return _IsDeleted;
            }
        }

        public bool IsLockedOut
        {
            get
            {
                return _IsLockedOut;
            }
        }

        public DateTime LastActivityDate
        {
            get
            {
                return _LastActivityDate;
            }
        }

        public DateTime LastLoginDate
        {
            get
            {
                return _LastLoginDate;
            }
        }

        public DateTime LastPasswordChangedDate
        {
            get
            {
                return _LastPasswordChangedDate;
            }
        }

        public DateTime LastLockoutDate
        {
            get
            {
                return _LastLockoutDate;
            }
        }

        public int FailedPwdAttemptCount
        {
            get
            {
                return _FailedPwdAttemptCount;
            }
        }

        public DateTime FailedPwdAttemptWindowStart
        {
            get
            {
                return _FailedPwdAttemptWindowStart;
            }
        }

        public int FailedPwdAnswerCount
        {
            get
            {
                return _FailedPwdAnswerCount;
            }
        }

        public DateTime FailedPwdAnswerWindowStart
        {
            get
            {
                return _FailedPwdAnswerWindowStart;
            }
        }

        public string PasswordSalt
        {
            get
            {
                return _PasswordSalt;
            }
            set
            {
                _PasswordSalt = value;
            }
        }

        public string Comment
        {
            get
            {
                return _Comment;
            }
        }

        public bool IsBuildInUser
        {
            get
            {
                return _IsBuildInUser;
            }
        }

        #endregion

        #region Static Properties

        public static SiteUser AutomaticAdmin
        {
            get
            {
                return GetAutomaticAdmin();
            }
        }

        #endregion

        #region Private Methods

        private void _GetUser(Guid _UserId)
        {
            this._GetUser(DBSiteUser.GetUser(_UserId));
        }

        private void _GetUser(string _SiteUserLoginName)
        {
            this._GetUser(DBSiteUser.GetSingleUserByLoginName(_SiteUserLoginName));
        }

        private void _GetUser(IDataReader reader)
        {
            if (reader == null)
                return;
            try
            {

                while (reader.Read())
                {
                    try
                    {
                        this._UserId = new Guid(reader["UserId"].ToString());
                    }
                    catch
                    {
                        this._UserId = Guid.Empty;
                    }

                    try
                    {
                        this._SiteId = new Guid(reader["SiteId"].ToString());
                    }
                    catch
                    {
                        this._SiteId = Guid.Empty;
                    }

                    this._LoginName = reader["LoginName"].ToString();
                    this._Email = reader["Email"].ToString();
                    this._Name = reader["Name"].ToString();
                    this._Password = reader["Password"].ToString();
                    try
                    {
                        if (reader["DateCreated"] != DBNull.Value)
                            this._DateCreated = (DateTime)reader["DateCreated"];
                    }
                    catch
                    {
                    }

                    string strIsDeleted = reader["IsDeleted"].ToString();
                    this._IsDeleted = (strIsDeleted == "True" || strIsDeleted == "1");
                    string strIsLockedOut = reader["IsLockedOut"].ToString();
                    this._IsLockedOut = (strIsLockedOut == "True" || strIsLockedOut == "1");

                    //try
                    //{
                    //    if (reader["LastActivityDate"] != DBNull.Value)
                    //        this._LastActivityDate = (DateTime)reader["LastActivityDate"];
                    //}
                    //catch { }

                    //try
                    //{
                    //    if (reader["LastLoginDate"] != DBNull.Value)
                    //        this._LastLoginDate = (DateTime)reader["LastLoginDate"];
                    //}
                    //catch { }
                    //try
                    //{
                    //    if (reader["LastPasswordChangedDate"] != DBNull.Value)
                    //        this._LastPasswordChangedDate = (DateTime)reader["LastPasswordChangedDate"];
                    //}
                    //catch { }
                    //try
                    //{
                    //    if (reader["LastLockoutDate"] != DBNull.Value)
                    //        this._LastLockoutDate = (DateTime)reader["LastLockoutDate"];
                    //}
                    //catch { }

                    //this._FailedPwdAttemptCount = Convert.ToInt32(reader["FailedPwdAttemptCount"]);

                    //try
                    //{
                    //    if (reader["FailedPwdAttemptWindowStart"] != DBNull.Value)
                    //        this._FailedPwdAttemptWindowStart = (DateTime)reader["FailedPwdAttemptWindowStart"];
                    //}
                    //catch { }

                    //this._FailedPwdAnswerCount = Convert.ToInt32(reader["FailedPwdAnswerCount"]);

                    //try
                    //{
                    //    if (reader["FailedPwdAnswerWindowStart"] != DBNull.Value)
                    //        this._FailedPwdAnswerWindowStart = (DateTime)reader["FailedPwdAnswerWindowStart"];
                    //}
                    //catch { }

                    //this._PasswordSalt = reader["PasswordSalt"].ToString();
                    //this._Comment = reader["Comment"].ToString();

                    string strIsBuildInUser = reader["IsBuildInUser"].ToString();
                    this._IsBuildInUser = (strIsBuildInUser == "True" || strIsBuildInUser == "1");
                }
            }
            finally 
            {
                reader.Close();
            }
            
            
        }

        private bool Create()
        {
            this._UserId = Guid.NewGuid();
            return DBSiteUser.Create(
            this._UserId,
            this._SiteId,
            this._LoginName,
            this._Email,
            this._Name,
            this._Password,
            DateTime.Now,
            this._PasswordSalt,
            this._Comment,
            this._IsBuildInUser);
        }

        private bool Update()
        {
            return DBSiteUser.Update(
            this._UserId,
            this._SiteId,
            this._LoginName,
            this._Email,
            this._Name,
            this._Password,
            this._PasswordSalt,
            this._Comment
            );
        }

        private bool UpdatePassword()
        {
            return DBSiteUser.UpdatePassword(
            this._UserId,
            this._Password,
            this._PasswordSalt
            );
        }

        #endregion

        #region Public Methods

        public bool Save()
        {
            if (this._UserId != Guid.Empty)
            {
                return Update();
            }
            else
            {
                return Create();
            }
        }

        public bool UpdatePassword(string newPassword, string newPasswordSalt)
        {
            if (this._UserId == Guid.Empty)
                return false;

            this._Password = newPassword;
            this._PasswordSalt = newPasswordSalt;

            return this.UpdatePassword();
        }

        #endregion

        #region Public Static Methods

        /// <summary>
        /// Lay tat ca cac doi tuong SiteUser co trong CSDL.
        /// </summary>
        /// <returns>IDataReader</returns>
        public static IDataReader GetUsers()
        {
            return DBSiteUser.GetUsers();
        }

        /// <summary>
        /// Lay tat ca cac doi tuong SiteUser co trong CSDL.
        /// </summary>
        /// <returns>IDataReader</returns>
        public static List<SiteUser> GetUserList()
        {
            List<SiteUser> list = new List<SiteUser>();

            using (IDataReader reader = DBSiteUser.GetUsers())
            {
                while (reader.Read())
                {
                    Guid userId = Guid.Empty;
                    try
                    {
                        userId = new Guid(reader["UserId"].ToString());
                    }
                    catch
                    {
                    }

                    if (userId != Guid.Empty)
                        list.Add(new SiteUser(userId));
                }
            }
            return list;
        }
        public static IDataReader GetUserByLoginName(string loginName)
        {
            return DBSiteUser.GetSingleUserByLoginName(loginName);
        }
        /// <summary>
        /// Xoa mot doi tuong SiteUser co trong CSDL theo Khoa chinh.
        /// </summary>
        public static bool Delete(Guid userId)
        {
            return DBSiteUser.Delete(userId);
        }
        public static bool ForceDelete(Guid userId)
        {
            return DBSiteUser.ForceDelete(userId);
        }
        public static IDataReader GetBySite(Guid siteId)
        {
            return DBSiteUser.GetBySite(siteId);
        }
        public static bool ChangePassword(Guid userId, string newPassword, string newPasswordSalt)
        {
            return DBSiteUser.UpdatePassword(
            userId,
            newPassword,
            newPasswordSalt
            );
        }
        public static bool LoginExistsInDB(string loginName)
        {
            bool found = false;

            using (IDataReader r = DBSiteUser.GetSingleUserByLoginName(loginName))
            {
                while (r.Read())
                {
                    found = true;
                }
            }

            return found;
        }
        public bool UnlockAccount()
        {
            //return DBSiteUser.AccountClearLockout(this.userGuid);
            throw new Exception("Không thể dùng trong phiên bản này");
        }
        public static string Login(string loginId, string password)
        {
            return DBSiteUser.Login(loginId, password);
        }
        public static IDataReader GetRolesByUser(Guid userId)
        {
            return DBSiteUser.GetRolesByUser(userId);
        }
        public static string[] GetRoles(string identity)
        {
            SiteUser siteSiteUser = new SiteUser(identity);

            ArrayList userRoles = new ArrayList();
            using (IDataReader reader = DBSiteUser.GetRolesByUser(siteSiteUser.UserId))
            {
                while (reader.Read())
                {
                    userRoles.Add(reader["RoleName"]);
                }
            }

            return (string[])userRoles.ToArray(typeof(string));
        }
        private static SiteUser GetAutomaticAdmin()
        {
            using (IDataReader reader = SiteUser.GetUserByLoginName("AutomaticAdmin"))
            {
                Guid id = Guid.Empty;
                while (reader.Read())
                {
                    id = new Guid(reader["UserId"].ToString());
                }
                if (id != Guid.Empty)
                {
                    return new SiteUser(id);
                }
            }


            // Create new
            SiteUser auto = new SiteUser();
            auto.LoginName = "AutomaticAdmin";
            auto.Name = "Quản Lý Tự Động";
            auto.Save();

            return auto;
        }

        // DZU THÊM
        public static string GetLoginNameByUserID(Guid userID)
        {
            using (IDataReader reader = DBSiteUser.GetLoginNameByUserID(userID))
            {
                while (reader.Read())
                {
                    return reader["LoginName"].ToString();
                }
            }
            return "";
        }
        
        //

        //tsandtm them
        public static List<SiteUser> GetAllUser(int pageNumber, int PageSize, out int totalPages)
        {
            totalPages = 1;
            List<SiteUser> list = new List<SiteUser>();
            using (IDataReader reader = DBSiteUser.GetAllUser(pageNumber, PageSize, out totalPages))
            {
                while (reader.Read())
                {
                    SiteUser user = new SiteUser(Guid.Parse(reader["UserId"].ToString()));
                    list.Add(user);
                }
            }
            return list;
        }
        public static bool EmailExistsInDB(string email)
        {
            bool found = false;
            using (IDataReader r = DBSiteUser.GetSingleUser(email))
            {
                while (r.Read()) { found = true; }
            }
            return found;
        }
        #endregion

        #region Add by tsandtm
        public static List<SiteUser> GetPageByRoleID(Guid roleID, int pageNumber, int pageSize, out int totalPages)
        {
            totalPages = 1;
            using (IDataReader reader = DBUserRoles.GetPageByRoleID(roleID, pageNumber, pageSize, out totalPages))
            {
                List<SiteUser> listItem = new List<SiteUser>();
                try
                {
                    while (reader.Read())
                    {
                        SiteUser item = new SiteUser();
                        item._UserId = new Guid(reader["UserId"].ToString());
                        item._Name = reader["Name"].ToString();
                        item._LoginName = reader["LoginName"].ToString();
                        listItem.Add(item);
                    }
                }
                catch
                {
                }
                return listItem;
            }
        }
        #endregion
    }
}
